package com.game.logic.channel;

import com.game.framework.common.error.EventExecutorGroup;
import io.netty.util.concurrent.EventExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;

@Slf4j
public class ServerChannelGroup {

	private Map<Object, ServerChannelContext> gameChannelMap = new HashMap<>();
	private EventExecutor executor;
	private EventExecutorGroup executorGroup;
	private ApplicationContext applicationContext;

	public ServerChannelGroup(EventExecutorGroup executorGroup, ApplicationContext context) {
		this.executor = executorGroup.select(0);
		this.executorGroup = executorGroup;
		this.applicationContext = context;
	}

	private void executeTask(Runnable task) {
		this.executor.execute(() -> {
			try {
				task.run();
			} catch (Throwable e) {
				log.error("执行任务失败", e);
			}
		});
	}

	public void gameChannelConsumer(Object key, Consumer<ServerChannelContext> consumer) {
		this.executeTask(() -> {
			ServerChannelContext serverChannelContext = this.gameChannelMap.get(key);
			if (serverChannelContext != null) {
				consumer.accept(serverChannelContext);
			} else {
				log.debug("不存在{} 对应的GameChannel，创建新的GameChannel", key);
				
				serverChannelContext = new ServerChannelContext(applicationContext,executorGroup.select(key), key.toString());
				this.gameChannelMap.put(key, serverChannelContext);
				consumer.accept(serverChannelContext);
			}
		});
	}
	

	public void removeGameChannel(Object key) {
		this.executeTask(() -> {
			gameChannelMap.remove(key);
		});
	}

	public Map<Object, ServerChannelContext> getGameChannelMap() {
		return gameChannelMap;
	}

	public void setGameChannelMap(Map<Object, ServerChannelContext> gameChannelMap) {
		this.gameChannelMap = gameChannelMap;
	}

	public EventExecutor getExecutor() {
		return executor;
	}

	public void setExecutor(EventExecutor executor) {
		this.executor = executor;
	}

	public EventExecutorGroup getExecutorGroup() {
		return executorGroup;
	}

	public void setExecutorGroup(EventExecutorGroup executorGroup) {
		this.executorGroup = executorGroup;
	}

	public ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	public void setApplicationContext(ApplicationContext context) {
		this.applicationContext = context;
	}
}
